#include "guilcd_sdl.h"
#include "core.h"
//#include "droptarget.h"


enum {
	ID_LCD,
};

unsigned char redColors[MAX_SHADES+1];
unsigned char greenColors[MAX_SHADES+1];
unsigned char blueColors[MAX_SHADES+1];
/*MyLCD(wxFrame *mainFrame, LPCALC lpCalc)
	: wxWindow(mainFrame, ID_LCD, wxPoint(0,0),
		wxSize(lpCalc->cpu.pio.lcd->width * lpCalc->scale, 64 * lpCalc->scale)) {
	this->lpCalc = lpCalc;
	int scale = lpCalc->scale;
	this->mainFrame = mainFrame;
	this->Connect(wxEVT_PAINT, wxPaintEventHandler(OnPaint));
	this->Connect(wxID_ANY, wxEVT_KEY_DOWN, (wxObjectEventFunction) &OnKeyDown);
	this->Connect(wxID_ANY, wxEVT_KEY_UP, (wxObjectEventFunction) &OnKeyUp);
	//this->Connect(wxEVT_SIZE, (wxObjectEventFunction) &OnResize);
	this->Connect(wxEVT_LEFT_DOWN, (wxObjectEventFunction) &OnLeftButtonDown);
	this->Connect(wxEVT_LEFT_UP, (wxObjectEventFunction) &OnLeftButtonUp);
	this->SetDropTarget(new DnDFile(this, lpCalc));*/
void initLCD() {
#define LCD_HIGH	255
	for (int i = 0; i <= MAX_SHADES; i++) {
		redColors[i] = (0x9E*(256-(LCD_HIGH/MAX_SHADES)*i))/255;
		greenColors[i] = (0xAB*(256-(LCD_HIGH/MAX_SHADES)*i))/255;
		blueColors[i] = (0x88*(256-(LCD_HIGH/MAX_SHADES)*i))/255;
	}
	//SDL_LockSurface(lcdsurface);
	printf_d("[SDLWabbitemu] [initLCD] Function called!\n");
}

/*void OnLeftButtonDown(wxMouseEvent& event)
{
	event.Skip(true);
	static wxPoint pt;
	keypad_t *kp = lpCalc->cpu.pio.keypad;

	//CopySkinToButtons();
	//CaptureMouse();
	pt.x	= event.GetX();
	pt.y	= event.GetY();

	for(int group = 0; group < 7; group++) {
		for(int bit = 0; bit < 8; bit++) {
			kp->keys[group][bit] &= (~KEY_MOUSEPRESS);
		}
	}

	lpCalc->cpu.pio.keypad->on_pressed &= ~KEY_MOUSEPRESS;


	if (lpCalc->keymap.GetRed(pt.x, pt.y) == 0xFF) {
		//FinalizeButtons(lpCalc);
		return;
	}

	int green = lpCalc->keymap.GetGreen(pt.x, pt.y);
	int blue = lpCalc->keymap.GetBlue(pt.x, pt.y);
	if ((green >> 4) == 0x05 && (blue >> 4) == 0x00)
	{
		lpCalc->cpu.pio.keypad->on_pressed |= KEY_MOUSEPRESS;
	} else {
		kp->keys[green >> 4][blue >> 4] |= KEY_MOUSEPRESS;
		if ((kp->keys[green >> 4][blue >> 4] & KEY_STATEDOWN) == 0) {
			//DrawButtonState(lpCalc, lpCalc->hdcButtons, lpCalc->hdcKeymap, &pt, DBS_DOWN | DBS_PRESS);
			kp->keys[green >> 4][blue >> 4] |= KEY_STATEDOWN;
		}
	}
}*/

/*void OnLeftButtonUp(wxMouseEvent& event)
{
	event.Skip(true);
	static wxPoint pt;
	keypad_t *kp = lpCalc->cpu.pio.keypad;

	ReleaseMouse();

	for(int group = 0; group < 7; group++) {
		for(int bit = 0; bit < 8; bit++) {
			kp->keys[group][bit] &= ~(KEY_MOUSEPRESS | KEY_STATEDOWN);
		}
	}

	lpCalc->cpu.pio.keypad->on_pressed &= ~KEY_MOUSEPRESS;
}*/

/*void OnResize(wxSizeEvent& event)
{
	event.Skip(false);
}*/

//TODO: forward these events somehow
void LCDOnKeyDown(SDL_KeyboardEvent& event)
{
	int keycode = event.keysym.sym;
	if (keycode == SDLK_F8) {
		if (lpCalc->speed == 100)
			lpCalc->speed = 400;
		else
			lpCalc->speed = 100;
	}
	/*if (keycode == WXK_SHIFT) {
		wxUint32 raw = event.GetRawKeyCode();
		if (raw == 65505) {
			keycode = WXK_LSHIFT;
		} else {
			keycode = WXK_RSHIFT;
		}
	}*/

	keyprog_t *kp = keypad_key_press(&lpCalc->cpu, keycode);
	if (kp) {
		if ((lpCalc->cpu.pio.keypad->keys[kp->group][kp->bit] & KEY_STATEDOWN) == 0) {
			lpCalc->cpu.pio.keypad->keys[kp->group][kp->bit] |= KEY_STATEDOWN;
			//this->Update();
			LCDFinalizeButtons();
		}
	}
}

void LCDOnKeyUp(SDL_KeyboardEvent& event)
{
	int key = event.keysym.sym;
	if ((key == SDLK_LSHIFT) || (key == SDLK_RSHIFT)) {
		keypad_key_release(&lpCalc->cpu, SDLK_LSHIFT);
		keypad_key_release(&lpCalc->cpu, SDLK_RSHIFT);
	} else {
		keypad_key_release(&lpCalc->cpu, key);
	}
	LCDFinalizeButtons();
}

void LCDFinalizeButtons() {
	int group, bit;
	keypad_t *kp = lpCalc->cpu.pio.keypad;
	for(group = 0; group < 7; group++) {
		for(bit = 0; bit < 8; bit++) {
			if ((kp->keys[group][bit] & KEY_STATEDOWN) &&
				((kp->keys[group][bit] & KEY_MOUSEPRESS) == 0) &&
				((kp->keys[group][bit] & KEY_KEYBOARDPRESS) == 0)) {
					kp->keys[group][bit] &= (~KEY_STATEDOWN);
			}
		}
	}
}

void LCDOnPaint()
{
	//printf_d("[SDLWabbitemu] [LCDOnPaint] Function called!\n");
	//wxPaintDC *dc = new wxPaintDC(this);
	if (lpCalc->SkinEnabled) {
		//this->Update();
		//wxBitmap skin = lpCalc->calcSkin;
		//dc->DrawBitmap(skin, 0, 0, true);
	}
	PaintLCD();
	LCD_t *lcd = lpCalc->cpu.pio.lcd;
	//wxStatusBar *wxStatus = mainFrame->GetStatusBar();
	//if (wxStatus) {
	//	if (clock() > lpCalc->sb_refresh + CLOCKS_PER_SEC / 2) {
	//		wxString sz_status;
			//if (lcd->active)
				//sz_status.sprintf(wxT("FPS: %0.2lf"), lcd->ufps);
				
			//else
				//sz_status.sprintf(wxT("FPS: -"));
			//wxStatus->SetStatusText(sz_status, 0);
			lpCalc->sb_refresh = clock();
	//	}
	//}
	//delete dc;
}

void PaintLCD()
{
	//printf_d("[SDLWabbitemu] [PaintLCD] Function called!\n");
	unsigned char *thescreen;
	LCD_t *lcd = lpCalc->cpu.pio.lcd;
	//wxSize rc = this->mainFrame->GetClientSize();
		int scale = lpCalc->scale;
	int draw_width = lcd->width * scale;
	int draw_height = 64 * scale;
	//wxPoint drawPoint((rc.GetWidth() - draw_width) / 2, 0);
	if (lpCalc->SkinEnabled) {
		//drawPoint.x = lpCalc->LCDRect.GetX();
		//drawPoint.y = lpCalc->LCDRect.GetY();
	}
	//wxMemoryDC wxMemDC;
	Sint32 x,y = 0;
	if (lcd->active == false) {
		unsigned char lcd_data[128*64];
		memset(lcd_data, 0, sizeof(lcd_data));
		unsigned char rgb_data[128*64*3];
		int i, j;
		for (i = j = 0; i < 128*64; i++, j+=3) {
			/*rgb_data[j] = redColors[lcd_data[i]];
			rgb_data[j+1] = greenColors[lcd_data[i]];
			rgb_data[j+2] = blueColors[lcd_data[i]];*/
			
			// SUPER UGLY HACK:
			// We count up and determine rows, columns and draw the pixel for each
			
			if (x == 128) {
				x = 0;
				y++;
			}
			DrawPixel(lcdsurface, redColors[lcd_data[i]], greenColors[lcd_data[i]], blueColors[lcd_data[i]], x, y);
			x++;
		}
		/*wxImage screenImage(128, 64, rgb_data, true);
		wxBitmap bmpBuf(screenImage.Scale(128 * scale, 64 * scale).Size(rc, wxPoint(0,0)));
		wxMemDC.SelectObject(bmpBuf);
		//copy to the screen
		wxDCDest->Blit(drawPoint.x, drawPoint.y, draw_width, draw_height, &wxMemDC, 0, 0);
		wxMemDC.SelectObject(wxNullBitmap);*/
		//lcdsurface->pixels = rgb_data;

	} else {
		thescreen = LCD_image( lpCalc->cpu.pio.lcd ) ;
		unsigned char rgb_data[128*64*3];
		int i, j;
		for (i = j = 0; i < 128*64; i++, j+=3) {
			/*rgb_data[j] = redColors[thescreen[i]];
			rgb_data[j+1] = greenColors[thescreen[i]];
			rgb_data[j+2] = blueColors[thescreen[i]];*/
			
			if (x == 128) {
				x = 0;
				y++;
			}
			DrawPixel(lcdsurface, redColors[thescreen[i]], greenColors[thescreen[i]], blueColors[thescreen[i]], x, y);
			x++;
		}
		
		/*wxImage screenImage(128, 64, rgb_data, true);
		wxBitmap bmpBuf(screenImage.Scale(128 * scale, 64 * scale).Size(rc, wxPoint(0,0)));
		wxMemDC.SelectObject(bmpBuf);
		
		//finally copy up the screen image
		wxDCDest->Blit(drawPoint.x, drawPoint.y, draw_width, draw_height, &wxMemDC, 0, 0);
		wxMemDC.SelectObject(wxNullBitmap);*/
		//lcdsurface->pixels = rgb_data;
	}
}

//TODO: BuckeyeDude: remove this and use fileutilities.c
void SaveStateDialog(LPCALC lpCalc) {
	char *FileName;
	/*wxString lpstrFilter 	= wxT("\
Known File types ( *.sav; *.rom; *.bin) |*.sav;*.rom;*.bin|\
Save States  (*.sav)|*.sav|\
ROMS  (*.rom; .bin)|*.rom;*.bin|\
All Files (*.*)|*.*\0");
	
	wxFileDialog dialog(NULL, wxT("Wabbitemu Save State"),
	wxT(""), wxT(""), lpstrFilter, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
	if (dialog.ShowModal() != wxID_OK)
		return;
	extern char * wxStringToChar(wxString);*/
	//FileName = wxStringToChar(dialog.GetPath());
	printf("[SDLWabbitemu] [LCD] Saving state to /tmp/savestate.bin...\n");
	FileName = "/tmp/savestate.bin";
	
	SAVESTATE_t* save = SaveSlot(lpCalc);

	strcpy(save->author, "Default");
	save->comment[0] = '\0';
	WriteSave(FileName, save, false);
	//gui_savestate(save, FileName);

}
